#include "axistiledmapview.h"
#include "axistiledmapscene.h"
#include <QApplication>
#include <QDebug>

AxisTiledMapView::AxisTiledMapView(QWidget* parent)
    : QGraphicsView(parent)
{
    setAttribute(Qt::WA_StaticContents);

    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

    setFrameShape(QFrame::NoFrame);
    setTransformationAnchor(QGraphicsView::AnchorViewCenter);

    QWidget* v = viewport();
    v->setMouseTracking(true);
    setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing);
    grabGesture(Qt::PinchGesture);
}

AxisTiledMapView::~AxisTiledMapView()
{

}

AxisTiledMapScene *AxisTiledMapView::mapScene() const
{
    return static_cast<AxisTiledMapScene*>(scene());
}

void AxisTiledMapView::setHandScrolling(bool b)
{
    if ( _handscrolling == b )
        return;

    _handscrolling = b;
}

void AxisTiledMapView::mousePressEvent(QMouseEvent *event)
{
    if ( Qt::MidButton == event->button() )
    {
        setHandScrolling(true);
        return;
    }
    QGraphicsView::mousePressEvent(event);
}

void AxisTiledMapView::mouseReleaseEvent(QMouseEvent *event)
{
    if ( Qt::MidButton == event->button() )
    {
        setHandScrolling(false);
        return;
    }
    QGraphicsView::mouseReleaseEvent(event);
}

void AxisTiledMapView::mouseMoveEvent(QMouseEvent *event)
{
    if ( _handscrolling )
    {
        const QPoint d = event->globalPos() - _lastmousepos;

        QScrollBar* hbar = horizontalScrollBar();
        QScrollBar* vbar = verticalScrollBar();
        hbar->setValue(hbar->value() + (isRightToLeft() ? d.x() : -d.x()));
        vbar->setValue(vbar->value() - d.y());

        _lastmousepos = event->globalPos();
        event->accept();
        return;
    }

    QGraphicsView::mouseMoveEvent(event);
    _lastmousepos = event->globalPos();
    _lastmousescenepos = mapToScene(viewport()->mapFromGlobal(_lastmousepos));
}

void AxisTiledMapView::wheelEvent(QWheelEvent *event)
{

}

void AxisTiledMapView::handlePinchGesture(QPinchGesture *pinch)
{
    setTransformationAnchor(QGraphicsView::NoAnchor);

    QPoint centerpoint = pinch->hotSpot().toPoint();
    adjustCenterFromMousePosition(centerpoint);

    setTransformationAnchor(QGraphicsView::AnchorViewCenter);
}

void AxisTiledMapView::adjustCenterFromMousePosition(QPoint &mousepos)
{
    QWidget* view = viewport();
    QPointF viewcenterscenepos = mapToScene(view->rect().center());
    QPointF mousescenepos = mapToScene(view->mapFromGlobal(mousepos));
    QPointF diff = viewcenterscenepos - mousescenepos;
    centerOn(_lastmousescenepos + diff);
}

bool AxisTiledMapView::event(QEvent *e)
{
    if ( e->type() == QEvent::Gesture )
    {
        QGestureEvent* gestureevent = static_cast<QGestureEvent*>(e);
        if ( QGesture* gesture = gestureevent->gesture(Qt::PinchGesture))
        {
            QPinchGesture* pinch = static_cast<QPinchGesture*>(gesture);
            if ( pinch->changeFlags() & QPinchGesture::ScaleFactorChanged )
            {
                handlePinchGesture(pinch);
            }
        }
    }
    return QGraphicsView::event(e);
}
